/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.func.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.func.funcPerm.FieldAuth.FieldAuthDataVo;
import com.je.common.base.func.funcPerm.FieldAuth.FieldAuthScopeVo;
import com.je.common.base.func.funcPerm.FieldAuth.FieldAuthVo;
import com.je.common.base.func.funcPerm.FieldAuth.FieldStateVo;
import com.je.common.base.func.funcPerm.dictionaryAuth.DictCanCelAuthScopeVo;
import com.je.common.base.func.funcPerm.dictionaryAuth.DictionaryAuthVo;
import com.je.common.base.func.funcPerm.dictionaryAuth.DictionaryVo;
import com.je.common.base.func.funcPerm.roleSqlAuth.RoleSqlAuthScopeVo;
import com.je.common.base.func.funcPerm.roleSqlAuth.RoleSqlAuthVo;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.*;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.cache.funcperm.FuncPermCache;
import com.je.meta.constant.FuncDataPermCons;
import com.je.meta.model.dd.DictionaryItemVo;
import com.je.meta.rpc.dictionary.DictionaryRpcService;
import com.je.meta.rpc.func.MetaFuncPermService;
import com.je.meta.service.func.FuncPermService;
import com.je.rbac.rpc.RoleRpcService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FuncPermServiceImpl implements FuncPermService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private DictionaryRpcService dictionaryRpcService;
    @Autowired
    private RoleRpcService roleRpcService;
    @Autowired
    private MetaFuncPermService metaFuncPermService;
    @Autowired
    private FuncPermCache funcPermCache;
    @Autowired
    private BeanService beanService;

    @Override
    @Transactional
    public DynaBean doUpdatePerm(DynaBean dynaBean) {
        /**
         * 暂不考虑租户
         */
        String type = dynaBean.getStr("type");
        String funcId = dynaBean.getStr("FUNCPERM_FUNCINFO_ID");
        String funcCode =dynaBean.getStr("FUNCPERM_FUNCINFO_CODE");
        String funcpermType = dynaBean.getStr("FUNCPERM_TYPE");
        DynaBean funcPerm =metaService.selectOne("JE_CORE_FUNCPERM",ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_ID",funcId).eq("FUNCPERM_TYPE",funcpermType));

        if (funcPerm == null) {

            if(FuncDataPermCons.FIELD_AUTH.equals(funcpermType)){
                checkData(dynaBean.getStr("FUNCPERM_CONFIG"));
            }
            String id = JEUUID.uuid();
            dynaBean.setStr("JE_CORE_FUNCPERM_ID",id);
            commonService.buildModelCreateInfo(dynaBean);
            String FUNCPERM_CONFIG = dynaBean.getStr("FUNCPERM_CONFIG");
            if("dictionaryAuth".equals(funcpermType)||"roleSqlAuth".equals(funcpermType)|| "fieldAuth".equals(funcpermType)){
                dynaBean.setStr("FUNCPERM_CONFIG","");
            }
            metaService.insert(dynaBean);
            saveOrUpdateChildTable(FUNCPERM_CONFIG,id,funcpermType);
        }else{
            dynaBean.setStr("JE_CORE_FUNCPERM_ID",funcPerm.getStr("JE_CORE_FUNCPERM_ID"));
            if("dictionaryAuth".equals(funcpermType)||"roleSqlAuth".equals(funcpermType)||"fieldAuth".equals(funcpermType)){
                saveOrUpdateChildTable(dynaBean.getStr("FUNCPERM_CONFIG"),funcPerm.getStr("JE_CORE_FUNCPERM_ID"),funcpermType);
                dynaBean.setStr("FUNCPERM_CONFIG","");
            }
            commonService.buildModelModifyInfo(dynaBean);
            metaService.update(dynaBean);
        }
        //存入缓存
        metaFuncPermService.putRedisCache(funcCode,funcpermType);
        return dynaBean;
    }

    private void checkData(String funcpermConfig) {
        FieldAuthVo fieldAuthVo = JSON.parseObject(funcpermConfig, FieldAuthVo.class);
        FieldAuthScopeVo fieldAuthDeptVo =fieldAuthVo.getDeptAuthFieldVo();
        FieldAuthScopeVo roleAuthFieldVo = fieldAuthVo.getRoleAuthFieldVo();
        FieldAuthScopeVo orgAuthFieldVo = fieldAuthVo.getOrgAuthFieldVo();
        if((fieldAuthDeptVo.getDatas()==null||fieldAuthDeptVo.getDatas().size()==0)
            &&(roleAuthFieldVo.getDatas()==null||roleAuthFieldVo.getDatas().size()==0)
            &&(orgAuthFieldVo.getDatas()==null||orgAuthFieldVo.getDatas().size()==0)){
            throw new PlatformException(MessageUtils.getMessage("function.dataPerm.field.configIsEmpty"), PlatformExceptionEnum.JE_CORE_TABLE_UPDATE_ERROR);
        }
    }

    private void saveOrUpdateChildTable(String funcpermConfig,String parentId,String funcpermType) {
        if("dictionaryAuth".equals(funcpermType)){
            DictionaryAuthVo dictionaryAuthVo = JSON.parseObject(funcpermConfig,DictionaryAuthVo.class);
            List<DictCanCelAuthScopeVo> deptList = dictionaryAuthVo.getDictCanCelAuthDeptList();
            if(deptList!=null&&deptList.size()>0){
                for(DictCanCelAuthScopeVo dept:deptList){
                    saveDictionaryhildData(dept,funcpermType,parentId,"dept");
                }
            }

            List<DictCanCelAuthScopeVo> orgList = dictionaryAuthVo.getDictCanCelAuthOrgList();
            if(orgList!=null&&orgList.size()>0){
                for(DictCanCelAuthScopeVo org:orgList){
                    saveDictionaryhildData(org,funcpermType,parentId,"org");
                }
            }
            List<DictCanCelAuthScopeVo> roleList = dictionaryAuthVo.getDictCanCelAuthRoleList();
            if(roleList!=null&&roleList.size()>0){
                for(DictCanCelAuthScopeVo role:roleList){
                    saveDictionaryhildData(role,funcpermType,parentId,"role");
                }
            }

        }

        if("roleSqlAuth".equals(funcpermType)){
            RoleSqlAuthVo roleSqlAuthVo = JSON.parseObject(funcpermConfig, RoleSqlAuthVo.class);
            List<RoleSqlAuthScopeVo> deptList = roleSqlAuthVo.getRoleSqlAuthDeptList();
            if(deptList!=null&&deptList.size()>0){
                for(RoleSqlAuthScopeVo dept:deptList){
                    saveRoleSqlChildData(dept,funcpermType,parentId,"dept");
                }
            }

            List<RoleSqlAuthScopeVo> orgList = roleSqlAuthVo.getRoleSqlAuthOrgList();
            if(orgList!=null&&orgList.size()>0){
                for(RoleSqlAuthScopeVo org:orgList){
                    saveRoleSqlChildData(org,funcpermType,parentId,"org");
                }
            }
            List<RoleSqlAuthScopeVo> roleList = roleSqlAuthVo.getRoleSqlAuthRoleList();
            if(roleList!=null&&roleList.size()>0){
                for(RoleSqlAuthScopeVo role:roleList){
                    saveRoleSqlChildData(role,funcpermType,parentId,"role");
                }
            }

        }

        if("fieldAuth".equals(funcpermType)){
            FieldAuthVo fieldAuthVo = JSON.parseObject(funcpermConfig, FieldAuthVo.class);
            FieldAuthScopeVo fieldAuthDeptVo =fieldAuthVo.getDeptAuthFieldVo();
            if(fieldAuthDeptVo!=null&&fieldAuthDeptVo.getDatas()!=null){
                for(FieldAuthDataVo fieldAuthDataVo:fieldAuthDeptVo.getDatas()){
                    saveFieldAuthChildData(fieldAuthDataVo,funcpermType,parentId,"dept",fieldAuthDeptVo.getControlScope(),fieldAuthDeptVo.getSelectControl());
                }
            }else {
                saveFieldAuthChildData(null,funcpermType,parentId,"dept",fieldAuthDeptVo.getControlScope(),fieldAuthDeptVo.getSelectControl());
            }
            FieldAuthScopeVo fieldAuthOrgVo =fieldAuthVo.getOrgAuthFieldVo();
            if(fieldAuthOrgVo!=null&&fieldAuthOrgVo.getDatas()!=null){
                for(FieldAuthDataVo fieldAuthDataVo:fieldAuthOrgVo.getDatas()){
                    saveFieldAuthChildData(fieldAuthDataVo,funcpermType,parentId,"org",fieldAuthOrgVo.getControlScope(),fieldAuthOrgVo.getSelectControl());
                }
            }else{
                saveFieldAuthChildData(null,funcpermType,parentId,"org",fieldAuthOrgVo.getControlScope(),fieldAuthOrgVo.getSelectControl());
            }
            FieldAuthScopeVo fieldAuthRoleVo = fieldAuthVo.getRoleAuthFieldVo();
            if(fieldAuthRoleVo!=null&&fieldAuthRoleVo.getDatas()!=null){
                for(FieldAuthDataVo fieldAuthDataVo:fieldAuthRoleVo.getDatas()){
                    saveFieldAuthChildData(fieldAuthDataVo,funcpermType,parentId,"role",fieldAuthRoleVo.getControlScope(),fieldAuthRoleVo.getSelectControl());
                }
            }else{
                saveFieldAuthChildData(null,funcpermType,parentId,"role",fieldAuthRoleVo.getControlScope(),fieldAuthRoleVo.getSelectControl());
            }
        }

    }

    private void saveFieldAuthChildData(FieldAuthDataVo fieldAuthDataVo, String funcpermType, String parentId, String dataType,String controlScope,String selectScope) {
        DynaBean dynaBean  =new DynaBean("JE_CORE_FUNCPERM_CONFIG",true);
        if(fieldAuthDataVo==null){
            if(StringUtil.isNotEmpty(controlScope)||StringUtil.isNotEmpty(selectScope)){
                if(StringUtil.isNotEmpty(controlScope)){
                    dynaBean.setStr("CONFIG_CONTROL_SCOPE",controlScope);
                }
                if(StringUtil.isNotEmpty(selectScope)){
                    dynaBean.setStr("CONFIG_SELECT_SCOPE",selectScope);
                }
                metaService.update(dynaBean,ConditionsWrapper.builder()
                        .eq("CONFIG_FUNCPERM_ID",parentId)
                        .eq("CONFIG_PERM_TYPE",funcpermType)
                        .eq("CONFIG_TYPE",dataType));
            }

        }else{
            DynaBean config= metaService.selectOne("JE_CORE_FUNCPERM_CONFIG",ConditionsWrapper.builder()
                    .eq("CONFIG_DATA_ID",fieldAuthDataVo.getId())
                    .eq("CONFIG_PERM_TYPE",funcpermType)
                    .eq("CONFIG_FUNCPERM_ID",parentId));
            if(config==null){
                dynaBean.setStr("CONFIG_FUNCPERM_ID",parentId);
                dynaBean.setStr("CONFIG_TYPE",dataType);
                dynaBean.set("CONFIG_INFO",JSON.toJSONString(fieldAuthDataVo));
                dynaBean.setStr("CONFIG_PERM_TYPE",funcpermType);
                dynaBean.setStr("CONFIG_DATA_ID",fieldAuthDataVo.getId());
                dynaBean.setStr("CONFIG_CONTROL_SCOPE",controlScope);
                dynaBean.setStr("CONFIG_SELECT_SCOPE",selectScope);
                commonService.buildModelCreateInfo(dynaBean);
                metaService.insert(dynaBean);
            }else{
                //如果全部为未勾选，则删除
                if(!checkFieldAuthData(fieldAuthDataVo)){
                    //删除该行数据
                    metaService.delete("JE_CORE_FUNCPERM_CONFIG",ConditionsWrapper.builder().eq("JE_CORE_FUNCPERM_CONFIG_ID",config.getStr("JE_CORE_FUNCPERM_CONFIG_ID")));
                }else{
                    dynaBean.setStr("JE_CORE_FUNCPERM_CONFIG_ID",config.getStr("JE_CORE_FUNCPERM_CONFIG_ID"));
                    dynaBean.set("CONFIG_INFO",JSON.toJSONString(fieldAuthDataVo));
                    dynaBean.setStr("CONFIG_CONTROL_SCOPE",controlScope);
                    dynaBean.setStr("CONFIG_SELECT_SCOPE",selectScope);
                    commonService.buildModelModifyInfo(dynaBean);
                    metaService.update(dynaBean);
                }
            }
        }
    }

    private boolean checkFieldAuthData(FieldAuthDataVo fieldAuthDataVo) {
        for(FieldStateVo fieldStateVo:fieldAuthDataVo.getAllFields()){
           String value = fieldStateVo.getValue();
           if("1".equals(value)){
               return true;
           }
        }
        return false;
    }

    private void saveRoleSqlChildData(RoleSqlAuthScopeVo roleSqlAuthScopeVo, String funcpermType, String parentId, String dataType) {
        DynaBean dynaBean  =new DynaBean("JE_CORE_FUNCPERM_CONFIG",true);
        DynaBean config= metaService.selectOne("JE_CORE_FUNCPERM_CONFIG",ConditionsWrapper.builder()
                .eq("CONFIG_DATA_ID",roleSqlAuthScopeVo.getId())
                .eq("CONFIG_PERM_TYPE",funcpermType)
                .eq("CONFIG_FUNCPERM_ID",parentId));
        if(config==null){
            dynaBean.setStr("CONFIG_FUNCPERM_ID",parentId);
            dynaBean.setStr("CONFIG_TYPE",dataType);
            dynaBean.set("CONFIG_INFO",JSON.toJSONString(roleSqlAuthScopeVo));
            dynaBean.setStr("CONFIG_DATA_ID",roleSqlAuthScopeVo.getId());
            dynaBean.setStr("CONFIG_PERM_TYPE",funcpermType);
            commonService.buildModelCreateInfo(dynaBean);
            metaService.insert(dynaBean);
        }else {
            dynaBean.setStr("JE_CORE_FUNCPERM_CONFIG_ID",config.getStr("JE_CORE_FUNCPERM_CONFIG_ID"));
            dynaBean.set("CONFIG_INFO",JSON.toJSONString(roleSqlAuthScopeVo));
            commonService.buildModelModifyInfo(dynaBean);
            metaService.update(dynaBean);
        }
    }

    private void saveDictionaryhildData(DictCanCelAuthScopeVo dictCanCelAuthScopeVo, String funcpermType, String parentId,String dataType) {
        DynaBean dynaBean  =new DynaBean("JE_CORE_FUNCPERM_CONFIG",true);
        DynaBean config= metaService.selectOne("JE_CORE_FUNCPERM_CONFIG",ConditionsWrapper.builder()
                .eq("CONFIG_DATA_ID",dictCanCelAuthScopeVo.getId())
                .eq("CONFIG_FUNCPERM_ID",parentId)
                .eq("CONFIG_PERM_TYPE",funcpermType));
        if(config==null){
            dynaBean.setStr("CONFIG_FUNCPERM_ID",parentId);
            dynaBean.setStr("CONFIG_TYPE",dataType);
            dynaBean.set("CONFIG_INFO",JSON.toJSONString(dictCanCelAuthScopeVo.getDictList()));
            dynaBean.setStr("CONFIG_DATA_ID",dictCanCelAuthScopeVo.getId());
            dynaBean.setStr("CONFIG_PERM_TYPE",funcpermType);
            commonService.buildModelCreateInfo(dynaBean);
            metaService.insert(dynaBean);
        }else {
            dynaBean.setStr("JE_CORE_FUNCPERM_CONFIG_ID",config.getStr("JE_CORE_FUNCPERM_CONFIG_ID"));
            dynaBean.set("CONFIG_INFO",JSON.toJSONString(dictCanCelAuthScopeVo.getDictList()));
            commonService.buildModelModifyInfo(dynaBean);
            metaService.update(dynaBean);
        }
    }


    @Override
    public List<DynaBean> getPermData(DynaBean dynaBean) {
        String FUNCPERM_TYPE = dynaBean.getStr("FUNCPERM_TYPE");
        String type =dynaBean.getStr("type");
        ConditionsWrapper conditionsWrapper = ConditionsWrapper.builder();
        conditionsWrapper.eq("FUNCPERM_FUNCINFO_ID",dynaBean.getStr("FUNCPERM_FUNCINFO_ID"));
        if(StringUtils.isNotEmpty(FUNCPERM_TYPE)){
            conditionsWrapper.eq("FUNCPERM_TYPE",dynaBean.getStr("FUNCPERM_TYPE"));
        }
        //如果是租户则增加租户条件
        if("ZH".equals(type)){
            conditionsWrapper.eq("SY_TENANT_ID", SecurityUserHolder.getCurrentAccountTenantId());
        }
        List<DynaBean> authList = metaService.select("JE_CORE_FUNCPERM", conditionsWrapper);
        if(authList!=null&&authList.size()>0){
            for(DynaBean authItem:authList){
              String itemType =  authItem.getStr("FUNCPERM_TYPE");
              if("dictionaryAuth".equals(itemType)||"roleSqlAuth".equals(itemType) ||"fieldAuth".equals(itemType)){
                  String JE_CORE_FUNCPERM_ID =   authItem.getStr("JE_CORE_FUNCPERM_ID");
                  List<DynaBean> dataList = metaService.select("JE_CORE_FUNCPERM_CONFIG",ConditionsWrapper.builder().eq("CONFIG_FUNCPERM_ID",JE_CORE_FUNCPERM_ID));
                  //字典授权
                  DictionaryAuthVo dictionaryAuthVo = new DictionaryAuthVo();
                  List<DictCanCelAuthScopeVo> deptDict = new ArrayList();
                  dictionaryAuthVo.setDictCanCelAuthDeptList(deptDict);
                  List<DictCanCelAuthScopeVo> orgDict = new ArrayList();
                  dictionaryAuthVo.setDictCanCelAuthOrgList(orgDict);
                  List<DictCanCelAuthScopeVo> roleDict = new ArrayList();
                  dictionaryAuthVo.setDictCanCelAuthRoleList(roleDict);
                  //角色sql授权
                  RoleSqlAuthVo roleSqlAuthVo = new RoleSqlAuthVo();
                  List<RoleSqlAuthScopeVo> deptRoleSql =new ArrayList<>();
                  roleSqlAuthVo.setRoleSqlAuthDeptList(deptRoleSql);
                  List<RoleSqlAuthScopeVo> orgRoleSql =new ArrayList<>();
                  roleSqlAuthVo.setRoleSqlAuthOrgList(orgRoleSql);
                  List<RoleSqlAuthScopeVo> roleRoleSql =new ArrayList<>();
                  roleSqlAuthVo.setRoleSqlAuthRoleList(roleRoleSql);
                  //字段授权
                  FieldAuthVo fieldAuthVo = new FieldAuthVo();
                  FieldAuthScopeVo roleAuthFieldVo = new FieldAuthScopeVo();
                  List<FieldAuthDataVo> roleDatas = new ArrayList<>();
                  roleAuthFieldVo.setDatas(roleDatas);
                  fieldAuthVo.setRoleAuthFieldVo(roleAuthFieldVo);
                  FieldAuthScopeVo deptAuthFieldVo = new FieldAuthScopeVo();
                  List<FieldAuthDataVo> deptDatas = new ArrayList<>();
                  deptAuthFieldVo.setDatas(deptDatas);
                  fieldAuthVo.setDeptAuthFieldVo(deptAuthFieldVo);
                  FieldAuthScopeVo orgAuthFieldVo = new FieldAuthScopeVo();
                  List<FieldAuthDataVo> orgDatas = new ArrayList<>();
                  orgAuthFieldVo.setDatas(orgDatas);
                  fieldAuthVo.setOrgAuthFieldVo(orgAuthFieldVo);
                  for(DynaBean data:dataList){
                      String dataType = data.getStr("CONFIG_TYPE");
                      String dataId = data.getStr("CONFIG_DATA_ID");
                      String configInfo = data.getStr("CONFIG_INFO");
                      String CONFIG_CONTROL_SCOPE  =data.getStr("CONFIG_CONTROL_SCOPE");
                      String CONFIG_SELECT_SCOPE =data.getStr("CONFIG_SELECT_SCOPE");
                      if("fieldAuth".equals(itemType)){
                          if("org".equals(dataType)){
                              FieldAuthDataVo fieldAuthDataVo  =JSON.parseObject(configInfo, FieldAuthDataVo.class);
                              orgDatas.add(fieldAuthDataVo);
                              orgAuthFieldVo.setControlScope(CONFIG_CONTROL_SCOPE);
                              orgAuthFieldVo.setSelectControl(CONFIG_SELECT_SCOPE);
                          }
                          if("dept".equals(dataType)){
                              FieldAuthDataVo fieldAuthDataVo  =JSON.parseObject(configInfo, FieldAuthDataVo.class);
                              deptDatas.add(fieldAuthDataVo);
                              deptAuthFieldVo.setControlScope(CONFIG_CONTROL_SCOPE);
                              deptAuthFieldVo.setSelectControl(CONFIG_SELECT_SCOPE);
                          }
                          if("role".equals(dataType)){
                              FieldAuthDataVo fieldAuthDataVo  =JSON.parseObject(configInfo, FieldAuthDataVo.class);
                              roleDatas.add(fieldAuthDataVo);
                              roleAuthFieldVo.setSelectControl(CONFIG_SELECT_SCOPE);
                              roleAuthFieldVo.setControlScope(CONFIG_CONTROL_SCOPE);
                          }
                      }
                      if("dictionaryAuth".equals(itemType)){
                         //[{"childCode":"WAIT,SUSPEND","code":"JE_AUDFLAG"}]
                          DictCanCelAuthScopeVo dictCanCelAuthScopeVo = new DictCanCelAuthScopeVo();
                          dictCanCelAuthScopeVo.setId(dataId);
                          List<DictionaryVo> list= JSON.parseArray(configInfo, DictionaryVo.class);
                          dictCanCelAuthScopeVo.setDictList(list);
                          if("org".equals(dataType)){
                              orgDict.add(dictCanCelAuthScopeVo);
                          }
                          if("dept".equals(dataType)){
                              deptDict.add(dictCanCelAuthScopeVo);
                          }
                          if("role".equals(dataType)){
                              roleDict.add(dictCanCelAuthScopeVo);
                          }
                      }
                      if("roleSqlAuth".equals(itemType)){
                          RoleSqlAuthScopeVo roleSqlAuthScopeVo = new RoleSqlAuthScopeVo();
                          roleSqlAuthScopeVo.setId(dataId);
                          JSONObject jsonObject = JSON.parseObject(configInfo);
                          roleSqlAuthScopeVo.setSql(jsonObject.getString("sql"));
                          roleSqlAuthScopeVo.setCoverSql(jsonObject.getString("coverSql"));
                          if("org".equals(dataType)){
                              orgRoleSql.add(roleSqlAuthScopeVo);
                          }
                          if("dept".equals(dataType)){
                              deptRoleSql.add(roleSqlAuthScopeVo);
                          }
                          if("role".equals(dataType)){
                              roleRoleSql.add(roleSqlAuthScopeVo);
                          }
                      }
                  }
                  if("dictionaryAuth".equals(itemType)){
                      authItem.set("FUNCPERM_CONFIG",JSON.toJSONString(dictionaryAuthVo));
                  }
                  if("roleSqlAuth".equals(itemType)){
                      authItem.set("FUNCPERM_CONFIG",JSON.toJSONString(roleSqlAuthVo));
                  }
                  if("fieldAuth".equals(itemType)){
                      authItem.set("FUNCPERM_CONFIG",JSON.toJSONString(fieldAuthVo));
                  }
              }
              buildRetureData(itemType,authItem,dynaBean);
            }
        }else{
            DynaBean authItem = new DynaBean();
            buildRetureData(FUNCPERM_TYPE,authItem,dynaBean);
            authList.add(authItem);
        }
        return authList;
    }

    private void buildRetureData(String itemType, DynaBean authItem,DynaBean parm) {
        JSONTreeNode roleTree =roleRpcService.buildRoleTreeByRoleIds(null,false);
        if("fieldAuth".equals(itemType)){
            //装配角色树信息
            authItem.set("roleTree",roleTree);
            //装配字段信息
            List<Map<String,Object>> columnList=  metaService.selectSql("SELECT RESOURCEFIELD_CODE,RESOURCEFIELD_NAME,JE_CORE_RESOURCEFIELD_ID FROM JE_CORE_RESOURCEFIELD WHERE RESOURCEFIELD_XTYPE NOT IN ('fieldset','child','displayfield','childfuncfield') AND RESOURCEFIELD_FUNCINFO_ID={0} AND RESOURCEFIELD_HIDDEN='0' ORDER BY SY_ORDERINDEX ASC",parm.getStr("FUNCPERM_FUNCINFO_ID"));
            authItem.set("columnList",columnList);
        }
        if("dictionaryAuth".equals(itemType)){
            //装配角色树信息
            authItem.set("roleTree",roleTree);
            //装配字典信息
            List<Map<String,Object>> dictList = getFuncFieldDic(parm.getStr("FUNCPERM_FUNCINFO_ID"), (Boolean) parm.get("en"));
            authItem.set("dictList",dictList);
        }
        if("roleSqlAuth".equals(itemType)){
            //装配角色树信息
            authItem.set("roleTree",roleTree);
        }
    }


    @Override
    public List<Map<String,Object>> getFuncFieldDic(String funcId,Boolean en) {

        List<DynaBean> fields = metaService.select("JE_CORE_RESOURCEFIELD",ConditionsWrapper.builder()
                .eq("RESOURCEFIELD_FUNCINFO_ID",funcId)
                .in("RESOURCEFIELD_XTYPE","rgroup","cgroup","cbbfield","treessfield","treessareafield","barfield")
                .selectColumns("JE_CORE_RESOURCEFIELD_ID,RESOURCEFIELD_CONFIGINFO"));
        List<String> ddCodes=new ArrayList<String>();
        for(DynaBean field:fields){
            String configInfo=field.getStr("RESOURCEFIELD_CONFIGINFO","");
            if(StringUtil.isNotEmpty(configInfo)){
                String ddCode=configInfo.split(",")[0];
                if(StringUtil.isNotEmpty(ddCode)&&!ddCodes.contains(ddCode)){
                    ddCodes.add(ddCode);
                }
            }
        }
        List<Map<String,Object>> list = new ArrayList<>();
        for(String code:ddCodes){
           DynaBean dynaBean = metaService.selectOne("JE_CORE_DICTIONARY",ConditionsWrapper.builder()
                    .eq("DICTIONARY_DDCODE",code).apply("and (SY_STATUS = '' or SY_STATUS = '1')")
                   .selectColumns("JE_CORE_DICTIONARY_ID,DICTIONARY_DDCODE,DICTIONARY_DDNAME"));

            List<DictionaryItemVo> items=null;
           if(dynaBean!=null){
               items  =dictionaryRpcService.buildChildrenList(dynaBean,en,new Query(),"");
               Map<String,Object> map = new HashMap<>();
               map.put("code",dynaBean.getStr("DICTIONARY_DDCODE"));
               map.put("text",dynaBean.getStr("DICTIONARY_DDNAME"));
               map.put("item",items);
               list.add(map);
           }
        }
        return list;
    }

    @Override
    public void restoreDefault(String funcCode) {
        metaService.delete("JE_CORE_FUNCPERM",ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_CODE",funcCode));
        //清除缓存
        metaFuncPermService.restoreDefault(funcCode);
    }

    @Override
    public Map<String, Object> getFuncConfigInfo(String funcCode) {
        Map<String,Object> redisMap = new HashMap<>();
        /**
         *  字段,以后加上租户
         *  选择控制、控制范围，都是or的关系
         */
        Map<String,Object> fieldMap =getDataPermFieldConfig(funcCode);
        redisMap.put("field",fieldMap);
        
        /**
         * 字典
         */
        Map<String,Object> map = getDataPermDictConfig(funcCode);
        redisMap.put("dict",map);
        String currentTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        if(Strings.isNullOrEmpty(currentTenantId)){
            funcPermCache.putCache(funcCode,redisMap);
        }else {
            funcPermCache.putCache(currentTenantId,funcCode,redisMap);
        }

        return redisMap;
    }

    @Override
    public JSONTreeNode getTree(BaseMethodArgument param, HttpServletRequest request) {
        List<DynaBean> productList = metaService.select("JE_PRODUCT_MANAGE",ConditionsWrapper.builder().eq("SY_STATUS","1").orderByAsc("PRODUCT_TYPE","SY_ORDERINDEX"));
        JSONTreeNode productRootNode = buildProductTree(productList);
        JSONTreeNode template = beanService.getTreeTemplate("JE_CORE_FUNCINFO");
        for(JSONTreeNode product:productRootNode.getChildren()){
            List<Map<String,Object>> funcList = metaService.selectSql(
                    "SELECT SY_PRODUCT_CODE,SY_PRODUCT_NAME,SY_ORDERINDEX,JE_CORE_FUNCINFO_ID,SY_PARENT,SY_NODETYPE,FUNCINFO_NODEINFOTYPE,FUNCINFO_FUNCNAME,FUNCINFO_FUNCCODE,SY_LAYER,FUNCINFO_TABLENAME,SY_PATH,SY_TREEORDERINDEX,SY_PRODUCT_ID FROM JE_CORE_FUNCINFO WHERE SY_PRODUCT_ID='"+product.getId()+"'");
            List<JSONTreeNode> jsonTreeNodeList = commonService.buildJsonTreeNodeList(template, funcList, null, null,false);
            JSONTreeNode childJSONTreeNode = commonService.buildJSONNewTree(jsonTreeNodeList, "ROOT");
            product.setChildren(childJSONTreeNode.getChildren());
        }
        return productRootNode;
    }

    private JSONTreeNode buildProductTree(List<DynaBean> productList) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        for(DynaBean product:productList){
            JSONTreeNode node = buildProductTreeNode(rootNode.getId(),product);
            if (node != null) {
                rootNode.getChildren().add(node);
            }
        }
        return rootNode;
    }



    private JSONTreeNode buildProductTreeNode( String id, DynaBean bean) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.getPkValue());
        node.setParent(id);
        node.setLeaf(true);
        node.setText(bean.getStr("PRODUCT_NAME"));
        node.setCode(bean.getStr("PRODUCT_CODE"));
        node.setIcon(bean.getStr("PRODUCT_ICON"));
        node.setOrderIndex(bean.getStr("SY_ORDERINDEX"));
        node.setNodeInfo(bean.getStr("PRODUCT_CODE"));
        node.setNodeType("GENERAL");
        node.setNodePath(bean.getPkValue());
        node.setDisabled("");
        node.setDescription(bean.getStr("PRODUCT_DESCRIBE"));
        node.setNodeInfoType("product");
        //node.setBean(bean.getValues());
        return node;
    }

    private Map<String,Object> getDataPermFieldConfig(String funcCode) {
        FieldAuthVo fieldAuthVo =  metaFuncPermService.getFiledAuth(funcCode);
        Map<String,Object> resultCode =new HashMap<>();
        if(fieldAuthVo==null){
            return resultCode;
        }
        DynaBean dynaBean = metaService.selectOne("JE_CORE_FUNCINFO",ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE",funcCode));
        List<Map<String,Object>> columnList=  metaService.selectSql("SELECT JE_CORE_RESOURCEFIELD_ID,RESOURCEFIELD_CODE FROM JE_CORE_RESOURCEFIELD WHERE RESOURCEFIELD_XTYPE NOT IN ('fieldset','child','displayfield','childfuncfield') AND RESOURCEFIELD_FUNCINFO_ID={0} AND RESOURCEFIELD_HIDDEN='0' ORDER BY SY_ORDERINDEX ASC",dynaBean.getStr("JE_CORE_FUNCINFO_ID"));
        Set<String> editFields = new HashSet<>();
        Set<String> showFields = new HashSet<>();
        //部门
        FieldAuthScopeVo deptAuthFieldVo =  fieldAuthVo.getDeptAuthFieldVo();
        if(deptAuthFieldVo!=null&&deptAuthFieldVo.getDatas()!=null){
            String deptControlScope = deptAuthFieldVo.getControlScope();
            String deptSelectControl = deptAuthFieldVo.getSelectControl();
            List<FieldAuthDataVo> deptFieldAuthDataVoList = deptAuthFieldVo.getDatas();
            //当前账号所属部门
            String accountDepartmentId = SecurityUserHolder.getCurrentAccountDepartment().getId();
            if(deptFieldAuthDataVoList.size()>0){
                for(FieldAuthDataVo fieldAuthDataVo:deptFieldAuthDataVoList){
                    if(fieldAuthDataVo.getId().equals(accountDepartmentId)){
                        bulidFieldList(deptControlScope,deptSelectControl,fieldAuthDataVo,editFields,showFields);
                    }
                }
            }

        }
        //角色
        FieldAuthScopeVo roleAuthFieldVo = fieldAuthVo.getRoleAuthFieldVo();
        String roleControlScope = roleAuthFieldVo.getControlScope();
        String roleSelectControl = roleAuthFieldVo.getSelectControl();
        if(roleAuthFieldVo!=null&&roleAuthFieldVo.getDatas()!=null){
            //当前账号所属角色ids
            List<String> roleIds = SecurityUserHolder.getCurrentAccount().getRoleIds();
           List<FieldAuthDataVo> roleFieldAuthDataVoList = roleAuthFieldVo.getDatas();
           if(roleFieldAuthDataVoList.size()>0){
               for(FieldAuthDataVo fieldAuthDataVo:roleFieldAuthDataVoList){
                   if(roleIds.contains(fieldAuthDataVo.getId())){
                       bulidFieldList(roleControlScope,roleSelectControl,fieldAuthDataVo,editFields,showFields);
                   }
               }
           }
        }
        //机构
        FieldAuthScopeVo orgAuthFieldVo =fieldAuthVo.getOrgAuthFieldVo();
        String orgControlScope = orgAuthFieldVo.getControlScope();
        String orgSelectControl = orgAuthFieldVo.getSelectControl();
        if(orgAuthFieldVo!=null&&orgAuthFieldVo.getDatas()!=null){
            List<FieldAuthDataVo> orgFieldAuthDataVoList = orgAuthFieldVo.getDatas();
            //当前账号所属机构
            String accountRealOrgId = SecurityUserHolder.getCurrentAccountRealOrgId();
            if(orgFieldAuthDataVoList.size()>0){
               for(FieldAuthDataVo fieldAuthDataVo:orgFieldAuthDataVoList){
                   if(fieldAuthDataVo.getId().equals(accountRealOrgId)){
                       bulidFieldList(orgControlScope,orgSelectControl,fieldAuthDataVo,editFields,showFields);
                   }
               }
            }
        }
        Map<String,Object> resultId =new HashMap<>();
        if(showFields.size()>0){
            for(String str:showFields){
                resultId.put(str,"show");
            }
        }
        if(editFields.size()>0){
            for(String str:editFields){
                resultId.put(str,"edit");
            }
        }
        for(Map<String,Object> map:columnList){
           String fieldId = map.get("JE_CORE_RESOURCEFIELD_ID").toString();
           String fieldCode =  map.get("RESOURCEFIELD_CODE").toString();
           if(resultId.containsKey(fieldId)){
               resultCode.put(fieldCode,resultId.get(fieldId));
           }
        }

        return resultCode;
    }

    /**
     *
     * @param controlScope： 0：查询；1：修改
     * @param selectControl :0:启用；1：禁用
     * @param fieldAuthDataVo
     * @param editFields
     * @param showFields
     */
    private void bulidFieldList(String controlScope, String selectControl, FieldAuthDataVo fieldAuthDataVo, Set<String> editFields, Set<String> showFields) {
        if(fieldAuthDataVo.getAllFields()!=null&&fieldAuthDataVo.getAllFields().size()>0){
            for(FieldStateVo fieldStateVo:fieldAuthDataVo.getAllFields()){
                String code = fieldStateVo.getCode();
                //1:勾选；0不勾选
                String value = fieldStateVo.getValue();
                if("0".equals(selectControl)){
                    if("1".equals(value)){
                        if("0".equals(controlScope)){
                            showFields.add(code);
                        }
                        if("1".equals(controlScope)){
                            editFields.add(code);
                        }
                    }
                }
                if("1".equals(selectControl)){
                    if("0".equals(value)){
                        if("0".equals(controlScope)){
                            showFields.add(code);
                        }
                        if("1".equals(controlScope)){
                            editFields.add(code);
                        }
                    }
                }
            }
        }
    }

    private Map<String, Object> getDataPermDictConfig(String funcCode) {
        DictionaryAuthVo dictionaryAuth = metaFuncPermService.getDictionaryAuth(funcCode);
        List<DictionaryVo> resultList = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        if(dictionaryAuth!=null){
            List<DictCanCelAuthScopeVo> roleList = dictionaryAuth.getDictCanCelAuthRoleList();
            List<String> roleIds = SecurityUserHolder.getCurrentAccount().getRoleIds();
            if((roleList!=null&&roleList.size()>0)&&(roleIds!=null&&roleIds.size()>0)){
                for(DictCanCelAuthScopeVo item:roleList){
                    if(roleIds.contains(item.getId())){
                        resultList.addAll(item.getDictList());
                    }
                }
            }
            String accountDepartmentId = SecurityUserHolder.getCurrentAccountDepartment().getId();
            List<DictCanCelAuthScopeVo> deptList = dictionaryAuth.getDictCanCelAuthDeptList();
            if(deptList!=null&&deptList.size()>0&&StringUtil.isNotEmpty(accountDepartmentId)){
                for(DictCanCelAuthScopeVo item:deptList){
                    if(accountDepartmentId.equals(item.getId())){
                        resultList.addAll(item.getDictList());
                    }
                }
            }
            List<DictCanCelAuthScopeVo> orgList = dictionaryAuth.getDictCanCelAuthOrgList();
            String accountRealOrgId = SecurityUserHolder.getCurrentAccountRealOrgId();
            for(DictCanCelAuthScopeVo item:orgList){
                if(accountRealOrgId.equals(item.getId())){
                    resultList.addAll(item.getDictList());
                }
            }
            if(resultList.size()>0){
                for(DictionaryVo item:resultList){
                    if(map.containsKey(item.getCode())){
                        map.put(item.getCode(),removeDuplicate(map.get(item.getCode())+","+item.getChildCode()));
                    }else {
                        map.put(item.getCode(),item.getChildCode());
                    }
                }
            }
        }
        return map;
    }

    public List<String> removeDuplicate(String str){
        if(StringUtil.isNotEmpty(str)){
            List<String> list = Arrays.asList(str.split(","));
            return list.stream().distinct().collect(Collectors.toList());
        }
        return null;
    }

}
